<?php
class Image {
	private $_aType = array (1 => 'gif', 2 => 'jpg', 3 => 'png', 4 => 'swf', 5 => 'psd', 6 => 'bmp', 7 => 'tiff', 8 => 'tiff', 9 => 'jpc', 10 => 'jp2', 11 => 'jpx', 12 => 'jb2', 13 => 'swc', 14 => 'iff', 15 => 'wbmp', 16 => 'xbm' );
	private $_aAllowType = array ('gif', 'jpg', 'png' );
	private $_rImg;
	private $_aInfo;
	private $_sUploadPath;
	private $_sTmpPath;
	
	public function __construct() {
		$this->_sUploadPath = ROOT . '/' . Base::getConf ( 'image.upload_path' );
		$this->_sTmpPath = ROOT . '/' . Base::getConf ( 'image.tmp_path' ) ? Base::getConf ( 'image.tmp_path' ) : 'cache/img';
	}
	
	public function upload($sFile, $sPath = NULL) {
		$aInfo = $this->getInfo ( $sFile );
		if ($aInfo && in_array ( $aInfo ['type'], $this->_aAllowType )) {
			$sId = md5_file ( $sFile );
			$iLevel = intval ( Base::getConf ( 'image.level' ) );
			$sPath = $this->_sUploadPath . '/';
			for($i = 0; $i < $iLevel; $i ++) {
				$sPath .= substr ( $sId, $i, 1 ) . '/';
			}
			Base::$oBase->File_md ( $sPath );
			if (! @move_uploaded_file ( $sFile, $sPath . $sId )) {
				@rename ( $sFile, $sPath . $sId );
			}
			return $sId;
		} else {
			return false;
		}
	}
	
	public function checkExist($sId) {
		$iLevel = intval ( Base::getConf ( 'image.level' ) );
		$sPath = $this->_sUploadPath . '/';
		for($i = 0; $i < $iLevel; $i ++) {
			$sPath .= substr ( $sId, $i, 1 ) . '/';
		}
		$sFile = $sPath . $sId;
		return is_file ( $sFile );
	}
	
	public function getPathById($sId) {
		$iLevel = intval ( Base::getConf ( 'image.level' ) );
		$sPath = $this->_sUploadPath . '/';
		for($i = 0; $i < $iLevel; $i ++) {
			$sPath .= substr ( $sId, $i, 1 ) . '/';
		}
		return $sPath . $sId;
	}
	
	public function show($sId, $iWidth = 0, $iHeight = 0) {
		if ($iWidth == 0 && $iHeight == 0) {
			$sPath = $this->_sUploadPath . '/';
		} else {
			$sPath = $this->_sTmpPath . '/';
		}
		$iLevel = intval ( Base::getConf ( 'image.level' ) );
		for($i = 0; $i < $iLevel; $i ++) {
			$sPath .= substr ( $sId, $i, 1 ) . '/';
		}
		if ($iWidth == 0 && $iHeight == 0) {
			$sFile = $sPath . $sId;
		} else {
			Base::$oBase->File_md ( $sPath );
		}
		if ($iWidth == 0 && $iHeight == 0) {
			$sFile = $sPath . $sId;
			$aInfo = Base::$oBase->Image_getInfo ( $sFile );
			$sMime = $aInfo ['mime'];
		} else {
			$sFile = $sPath . $sId . '_' . $iWidth . 'x' . $iHeight . '.jpg';
			$sMime = 'image/jpeg';
		}
		if (! is_file ( $sFile )) {
			$sSFile = $this->_sUploadPath . '/';
			for($i = 0; $i < $iLevel; $i ++) {
				$sSFile .= substr ( $sId, $i, 1 ) . '/';
			}
			$sSFile .= $sId;
			$this->open ( $sSFile );
			$this->resize ( $sFile, $iWidth, $iHeight );
			$this->close ();
			if (Base::getConf ( 'image.watermark' )) {
				Base::$oBase->Watermark_mark ( $sFile );
			}
		}
		if (filesize ( $sFile ) > 1000000) {
			$rFp = fopen ( $sFile, 'rb' );
			if ($rFp) {
				header ( 'Content-type: ' . $sMime );
				echo fread ( $rFp, filesize ( $sFile ) );
			}
			fclose ( $rFp );
		} else {
			header ( 'Content-type: ' . $sMime );
			echo file_get_contents ( $sFile );
		}
		exit ();
	}
	
	public function setAllowType($aType) {
		$this->_aAllowType = $aType;
	}
	
	public function open($sFile) {
		$aInfo = $this->getInfo ( $sFile );
		
		if (is_array ( $aInfo )) {
			$this->_aInfo = $aInfo;
		} else {
			return false;
		}
		
		if (! in_array ( $aInfo ['type'], $this->_aAllowType )) {
			return false;
		}
		
		switch ($aInfo ['type']) {
			case 'gif' :
				$rImg = @imagecreatefromgif ( $sFile );
				break;
			case 'jpg' :
				$rImg = @imagecreatefromjpeg ( $sFile );
				break;
			case 'png' :
				$rImg = @imagecreatefrompng ( $sFile );
				break;
			default :
				return false;
		}
		
		if (! $rImg) {
			return false;
		} else {
			$this->_rImg = $rImg;
			return $rImg;
		}
	}
	
	public function setImg($rImg, $aInfo = array()) {
		$this->_rImg = $rImg;
		$this->_aInfo = $aInfo;
	}
	
	public function getInfo($sFile) {
		$aInfo = @getimagesize ( $sFile );
		if (is_array ( $aInfo )) {
			list ( $iWidth, $iHeight, $iType, $sAttr ) = $aInfo;
			return array ('width' => $iWidth, 'height' => $iHeight, 'type' => $this->_aType [$iType], 'attr' => $sAttr );
		} else {
			return false;
		}
	}
	
	public function resize($sFile, $iWidth = 0, $iHeight = 0, $bProportion = true, $iQuality = 100) {
		if (! is_resource ( $this->_rImg )) {
			return false;
		}
		if ($iWidth == 0 && $iHeight == 0) {
			$iWidth = $this->_aInfo ['width'];
			$iHeight = $this->_aInfo ['height'];
		} elseif ($bProportion == true) {
			if ($iWidth == 0) {
				$iWidth = $iHeight * $this->_aInfo ['width'] / $this->_aInfo ['height'];
			} elseif ($iHeight == 0) {
				$iHeight = $iWidth * $this->_aInfo ['height'] / $this->_aInfo ['width'];
			} else {
				if ($iWidth / $iHeight > $this->_aInfo ['width'] / $this->_aInfo ['height']) {
					$iWidth = $iHeight * $this->_aInfo ['width'] / $this->_aInfo ['height'];
				} else {
					$iHeight = $iWidth * $this->_aInfo ['height'] / $this->_aInfo ['width'];
				}
			}
		}
		
		if ($iWidth >= $this->_aInfo ['width'] && $iHeight >= $this->_height) {
			$rImg = $this->_rImg;
		} else {
			$rImg = @imagecreatetruecolor ( $iWidth, $iHeight );
			if (! @imagecopyresampled ( $rImg, $this->_rImg, 0, 0, 0, 0, $iWidth, $iHeight, $this->_aInfo ['width'], $this->_aInfo ['height'] )) {
				return false;
			}
		}
		
		$sExt = strtolower ( substr ( $sFile, strrpos ( $sFile, '.' ) + 1 ) );
		switch ($sExt) {
			case 'gif' :
				$rRes = @imagegif ( $rImg, $sFile, $iQuality );
				break;
			case 'png' :
				$rRes = @imagepng ( $rImg, $sFile, $iQuality );
				break;
			default :
				$rRes = @imagejpeg ( $rImg, $sFile, $iQuality );
				break;
		}
		
		imagedestroy ( $rImg );
		if (! $rRes) {
			return false;
		} else {
			return true;
		}
	}
	
	public function getExif($sFile, $bSerialize = false) {
		try {
			if (! extension_loaded ( 'exif' )) {
				new ExceptionExt ( '模块exif没有安装' );
			}
		} catch ( ExceptionExt $e ) {
			$e->showError ();
		}
		
		$aData = @exif_read_data ( $sFile );
		if ($bSerialize) {
			return serialize ( $aData );
		} else {
			return $aData;
		}
	}
	
	public function close() {
		@imagedestroy ( $this->_rImg );
	}
	
	public function getFontList() {
	
	}
	
	public function getFontPath() {
	
	}
	
	public function create($iWidth, $iHeight) {
		$this->_rImg = imagecreatetruecolor ( $iWidth, $iHeight );
		$this->_aInfo ['width'] = $iWidth;
		$this->_aInfo ['height'] = $iHeight;
	}
	
	private function _setColor($sColor) {
		if (! is_resource ( $this->_rImg )) {
			return false;
		}
		
		$aColor = $this->str2rgb ( $sColor );
		return imagecolorallocate ( $this->_rImg, $aColor [0], $aColor [1], $aColor [2] );
	}
	
	public function setBackgroundColor($sColor) {
		$iColor = $this->_setColor ( $sColor );
		if ($iColor === false) {
			return false;
		} else {
			imagefilledrectangle ( $this->_rImg, 0, 0, $this->_aInfo ['width'] - 1, $this->_aInfo ['height'] - 1, $iColor );
			return true;
		}
	}
	
	public function addText($sText, $sColor = '#ffffff', $sFont = 'arial', $iLeft = 0, $iTop = 0, $iSize = 12, $iAngle = 0) {
		$iColor = $this->_setColor ( $sColor );
		if ($iColor === false) {
			return false;
		} else {
			imagettftext ( $this->_rImg, $iSize, $iAngle, $iLeft, $iTop + $iSize, $iColor, LIB . '/font/' . $sFont . '.ttf', $sText );
			return true;
		}
	}
	
	public function get($sType = 'png', $bShow = ture) {
		switch ($sType) {
			case 'png' :
				if ($bShow) {
					header ( "Content-type: image/png" );
				}
				imagepng ( $this->_rImg );
				break;
		}
	}
	
	public function str2rgb($sColor) {
		$aMatch = array ();
		preg_match ( '/(\w{2})(\w{2})(\w{2})$/', $sColor, $aMatch );
		if (count ( $aMatch ) == 4) {
			$aResult [0] = $aResult ['r'] = hexdec ( $aMatch [1] );
			$aResult [1] = $aResult ['g'] = hexdec ( $aMatch [2] );
			$aResult [2] = $aResult ['b'] = hexdec ( $aMatch [3] );
			return $aResult;
		} else {
			return false;
		}
	}
	
	public function getValidateCode() {
		$iWidth = Base::getConf ( 'validate.width' );
		if (! $iWidth) {
			$iWidth = 60;
		}
		$iHeight = Base::getConf ( 'validate.height' );
		if (! $iHeight) {
			$iHeight = 20;
		}
		$sFont = Base::getConf ( 'validate.font' );
		if (! $sFont) {
			$sFont = 'arial';
		}
		$iSize = Base::getConf ( 'validate.size' );
		if (! $iSize) {
			$iSize = 12;
		}
		$iLen = Base::getConf ( 'validate.len' );
		if (! $iLen) {
			$iLen = 4;
		}
		$sBackgroundColor = Base::getConf ( 'validate.background_color' );
		if (! $sBackgroundColor) {
			$sBackgroundColor = '#000000';
		}
		$sFontColor = Base::getConf ( 'validate.font_color' );
		if (! $sFontColor) {
			$sFontColor = '#ffffff';
		}
		
		$iAngle = Base::getConf ( 'validate.angle' );
		if (! $iAngle) {
			$iAngle = 0;
		}
		$sText = '23456789ABCEDFGHJKMNPQRSTUVWXYZabcdefghkmnpqrstuvwxyz';
		$this->create ( $iWidth, $iHeight );
		$this->setBackgroundColor ( $sBackgroundColor );
		$sCode = '';
		for($i = 0; $i < $iLen; $i ++) {
			$sChar = substr ( str_shuffle ( $sText ), 0, 1 );
			$iLeft = rand ( $iWidth / $iLen * $i + 2, $iWidth / $iLen * ($i + 1) - $iSize - 2 );
			$iTop = rand ( 2, $iHeight - $iSize - 2 );
			if (is_array ( $sFont )) {
				shuffle ( $sFont );
				$sThisFont = $sFont [0];
			} else {
				$sThisFont = $sFont;
			}
			if ($iAngle > 0) {
				$iThisAngle = rand ( '-' . $iAngle, $iAngle );
			} else {
				$iThisAngle = 0;
			}
			$this->addText ( $sChar, $sFontColor, $sThisFont, $iLeft, $iTop, $iSize, $iThisAngle );
			$sCode .= $sChar;
		}
		$_SESSION ['validatecode'] = md5 ( 'vc' . strtolower ( $sCode ) );
		$this->get ();
		$this->close ();
	}
	
	public function checkValidateCode($sCode) {
		if (trim ( $sCode ) && $_SESSION ['validatecode'] == md5 ( 'vc' . strtolower ( $sCode ) )) {
			return true;
		} else {
			return false;
		}
	}
	
	public function destroyValidateCode() {
		unset ( $_SESSION ['validatecode'] );
	}
}
?>